import * as path from 'path';
import * as fs from 'fs';
import { app, dialog, shell } from 'electron';

export class RegulationService {
  // 根据类型获取文件存储目录
  private static getDirByType(type: string): string {
    // 在应用数据目录下创建对应类型的文件夹
    const appDataPath = app.getPath('appData');
    const dirPath = path.join(appDataPath, 'sdcal_electron', type);
    
    // 确保目录存在
    if (!fs.existsSync(dirPath)) {
      fs.mkdirSync(dirPath, { recursive: true });
    }
    
    return dirPath;
  }

  /**
   * 加载指定类型的文件列表
   * @param type 文件类型 (regulation, literature, blueprint)
   * @returns 文件列表
   */
  static async loadRegulationsByType(type: string): Promise<Array<{id: string, name: string, size: string, date: string}>> {
    try {
      const dir = this.getDirByType(type);
      
      console.log(`尝试加载${type}文件列表，目录路径: ${dir}`);
      
      // 读取目录中的所有文件
      const files = await fs.promises.readdir(dir);
      console.log(`找到 ${files.length} 个文件`);
      
      // 获取文件信息
      const regulations = [];
      
      for (let i = 0; i < files.length; i++) {
        const file = files[i];
        
        // 处理文件
        const filePath = path.join(dir, file);
        
        try {
          // 使用异步方法获取文件信息
          const stats = await fs.promises.stat(filePath);
          
          // 格式化文件大小
          let size = '';
          if (stats.size < 1024) {
            size = `${stats.size} B`;
          } else if (stats.size < 1024 * 1024) {
            size = `${(stats.size / 1024).toFixed(1)} KB`;
          } else {
            size = `${(stats.size / (1024 * 1024)).toFixed(1)} MB`;
          }
          
          // 格式化日期
          const date = stats.mtime.toLocaleString('zh-CN', {
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit'
          });
          
          regulations.push({
            id: `${type}-${i}`,
            name: file,
            size: size,
            date: date
          });
          
          console.log(`加载文件信息: ${file}, 大小: ${size}, 修改日期: ${date}`);
        } catch (error) {
          console.warn(`无法获取文件信息: ${file}`, error);
        }
      }
      
      console.log(`成功加载 ${regulations.length} 个${type}文件信息`);
      return regulations;
    } catch (error) {
      console.error(`加载${type}文件列表失败:`, error);
      throw new Error(`Failed to load ${type} files: ${(error as Error).message}`);
    }
  }

  /**
   * 添加指定类型的文件
   * @param type 文件类型 (regulation, literature, blueprint)
   * @param fileName 文件名
   * @param fileData Base64编码的文件数据
   */
  static async addRegulationByType(type: string, fileName: string, fileData: string): Promise<void> {
    try {
      const dir = this.getDirByType(type);
      const filePath = path.join(dir, fileName);
      
      console.log(`尝试添加${type}文件: ${fileName}`);
      console.log(`文件完整路径: ${filePath}`);
      
      // 检查文件是否已存在
      const exists = await fs.promises.access(filePath).then(() => true).catch(() => false);
      console.log(`文件是否存在: ${exists}`);
      
      if (exists) {
        // 如果文件已存在，添加时间戳避免覆盖
        const timestamp = Date.now();
        const ext = path.extname(fileName);
        const baseName = path.basename(fileName, ext);
        const newFileName = `${baseName}_${timestamp}${ext}`;
        const newFilePath = path.join(dir, newFileName);
        
        console.log(`文件已存在，使用新文件名: ${newFileName}`);
        // 写入文件
        await fs.promises.writeFile(newFilePath, Buffer.from(fileData, 'base64'));
      } else {
        // 写入新文件
        await fs.promises.writeFile(filePath, Buffer.from(fileData, 'base64'));
      }
      
      console.log(`成功添加${type}文件: ${fileName}`);
    } catch (error) {
      console.error(`添加${type}文件失败:`, error);
      throw new Error(`Failed to add ${type} file: ${(error as Error).message}`);
    }
  }

  /**
   * 删除指定类型的文件
   * @param type 文件类型 (regulation, literature, blueprint)
   * @param fileName 文件名
   */
  static async deleteRegulationByType(type: string, fileName: string): Promise<void> {
    try {
      const dir = this.getDirByType(type);
      const filePath = path.join(dir, fileName);
      
      console.log(`尝试删除${type}文件: ${fileName}`);
      console.log(`文件完整路径: ${filePath}`);
      
      // 检查文件是否存在
      const exists = await fs.promises.access(filePath).then(() => true).catch(() => false);
      console.log(`文件是否存在: ${exists}`);
      
      if (exists) {
        // 使用异步方法删除文件
        await fs.promises.unlink(filePath);
        console.log(`成功删除${type}文件: ${fileName}`);
      } else {
        console.error(`文件不存在: ${filePath}`);
        throw new Error(`File not found: ${fileName}`);
      }
    } catch (error) {
      console.error(`删除${type}文件失败:`, error);
      throw new Error(`Failed to delete ${type} file: ${(error as Error).message}`);
    }
  }

  /**
   * 打开指定类型的文件
   * @param type 文件类型 (regulation, literature, blueprint)
   * @param fileName 文件名
   */
  static async openRegulationByType(type: string, fileName: string): Promise<void> {
    try {
      const dir = this.getDirByType(type);
      const filePath = path.join(dir, fileName);
      
      console.log(`尝试打开${type}文件: ${fileName}`);
      console.log(`文件完整路径: ${filePath}`);
      
      // 检查文件是否存在
      const exists = await fs.promises.access(filePath).then(() => true).catch(() => false);
      console.log(`文件是否存在: ${exists}`);
      
      if (exists) {
        // 使用系统默认程序打开文件
        const result = await shell.openPath(filePath);
        
        // shell.openPath在Windows上成功时返回空字符串
        if (result === '') {
          console.log(`成功打开${type}文件: ${fileName}`);
        } else {
          console.error(`打开文件失败，错误信息: ${result}`);
          throw new Error(`Failed to open file: ${result}`);
        }
      } else {
        console.error(`文件不存在: ${filePath}`);
        throw new Error(`File not found: ${fileName}`);
      }
    } catch (error) {
      console.error(`打开${type}文件失败:`, error);
      throw new Error(`Failed to open ${type} file: ${(error as Error).message}`);
    }
  }

  /**
   * 保存指定类型的文件到用户选择的位置
   * @param type 文件类型 (regulation, literature, blueprint)
   * @param fileName 文件名
   */
  static async saveRegulationToUserLocationByType(type: string, fileName: string): Promise<string> {
    try {
      const dir = this.getDirByType(type);
      const sourceFilePath = path.join(dir, fileName);
      
      console.log(`尝试保存${type}文件到用户选择的位置: ${fileName}`);
      console.log(`源文件完整路径: ${sourceFilePath}`);
      
      // 检查文件是否存在
      const exists = await fs.promises.access(sourceFilePath).then(() => true).catch(() => false);
      console.log(`文件是否存在: ${exists}`);
      
      if (!exists) {
        console.error(`文件不存在: ${sourceFilePath}`);
        throw new Error(`File not found: ${fileName}`);
      }
      
      // 显示保存对话框让用户选择保存位置
      const result = await dialog.showSaveDialog({
        title: '保存文件',
        defaultPath: fileName,
        filters: [
          { name: 'PDF文件', extensions: ['pdf'] },
          { name: 'DWG文件', extensions: ['dwg'] },
          { name: 'DOC文件', extensions: ['doc','docx'] },
          { name: '所有文件', extensions: ['*'] }
        ]
      }) as unknown as Electron.SaveDialogReturnValue;
      
      // 检查是否取消或没有选择文件路径
      if (result.canceled || !result.filePath) {
        console.log('用户取消了保存操作');
        throw new Error('保存操作已取消');
      }
      
      // 复制文件到用户选择的位置
      await fs.promises.copyFile(sourceFilePath, result.filePath);
      
      console.log(`成功保存${type}文件到: ${result.filePath}`);
      return result.filePath;
    } catch (error) {
      console.error(`保存${type}文件失败:`, error);
      throw new Error(`Failed to save ${type} file: ${(error as Error).message}`);
    }
  }
}